package cloud.seri.auth.web.rest

import cloud.seri.auth.SeriAuthApp

import cloud.seri.auth.config.SecurityBeanOverrideConfiguration

import cloud.seri.auth.domain.Role
import cloud.seri.auth.repository.RoleRepository
import cloud.seri.auth.service.RoleService
import cloud.seri.auth.service.dto.RoleDTO
import cloud.seri.auth.service.mapper.RoleMapper
import cloud.seri.auth.web.rest.errors.ExceptionTranslator

import kotlin.test.assertNotNull

import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockitoAnnotations
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.web.PageableHandlerMethodArgumentResolver
import org.springframework.http.MediaType
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.validation.Validator



import cloud.seri.auth.web.rest.TestUtil.createFormattingConversionService
import org.assertj.core.api.Assertions.assertThat
import org.hamcrest.Matchers.hasItem
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

/**
 * Test class for the RoleResource REST controller.
 *
 * @see RoleResource
 */
@RunWith(SpringRunner::class)
@SpringBootTest(classes = [SeriAuthApp::class])
class RoleResourceIT {

    @Autowired
    private lateinit var roleRepository: RoleRepository

    @Autowired
    private lateinit var roleMapper: RoleMapper

    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var jacksonMessageConverter: MappingJackson2HttpMessageConverter

    @Autowired
    private lateinit var pageableArgumentResolver: PageableHandlerMethodArgumentResolver

    @Autowired
    private lateinit var exceptionTranslator: ExceptionTranslator

    @Autowired
    private lateinit var validator: Validator

    private lateinit var restRoleMockMvc: MockMvc

    private lateinit var role: Role

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        val roleResource = RoleResource(roleService)
        this.restRoleMockMvc = MockMvcBuilders.standaloneSetup(roleResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build()
    }

    @Before
    fun initTest() {
        roleRepository.deleteAll()
        role = createEntity()
    }

    @Test
    fun createRole() {
        val databaseSizeBeforeCreate = roleRepository.findAll().size

        // Create the Role
        val roleDTO = roleMapper.toDto(role)
        restRoleMockMvc.perform(
            post("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isCreated)

        // Validate the Role in the database
        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeCreate + 1)
        val testRole = roleList[roleList.size - 1]
        assertThat(testRole.roleName).isEqualTo(DEFAULT_ROLE_NAME)
        assertThat(testRole.roleAlias).isEqualTo(DEFAULT_ROLE_ALIAS)
        assertThat(testRole.status).isEqualTo(DEFAULT_STATUS)
        assertThat(testRole.sort).isEqualTo(DEFAULT_SORT)
        assertThat(testRole.remark).isEqualTo(DEFAULT_REMARK)
    }

    @Test
    fun createRoleWithExistingId() {
        val databaseSizeBeforeCreate = roleRepository.findAll().size

        // Create the Role with an existing ID
        role.id = "existing_id"
        val roleDTO = roleMapper.toDto(role)

        // An entity with an existing ID cannot be created, so this API call must fail
        restRoleMockMvc.perform(
            post("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isBadRequest)

        // Validate the Role in the database
        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeCreate)
    }


    @Test
    fun checkRoleNameIsRequired() {
        val databaseSizeBeforeTest = roleRepository.findAll().size
        // set the field null
        role.roleName = null

        // Create the Role, which fails.
        val roleDTO = roleMapper.toDto(role)

        restRoleMockMvc.perform(
            post("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isBadRequest)

        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeTest)
    }

    @Test
    fun checkStatusIsRequired() {
        val databaseSizeBeforeTest = roleRepository.findAll().size
        // set the field null
        role.status = null

        // Create the Role, which fails.
        val roleDTO = roleMapper.toDto(role)

        restRoleMockMvc.perform(
            post("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isBadRequest)

        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeTest)
    }

    @Test
    fun getAllRoles() {
        // Initialize the database
        roleRepository.save(role)

        // Get all the roleList
        restRoleMockMvc.perform(get("/api/roles?sort=id,desc"))
            .andExpect(status().isOk)
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(role.id)))
            .andExpect(jsonPath("$.[*].roleName").value(hasItem(DEFAULT_ROLE_NAME)))
            .andExpect(jsonPath("$.[*].roleAlias").value(hasItem(DEFAULT_ROLE_ALIAS)))
            .andExpect(jsonPath("$.[*].status").value(hasItem(DEFAULT_STATUS)))
            .andExpect(jsonPath("$.[*].sort").value(hasItem(DEFAULT_SORT)))
            .andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK)))
    }
    
    @Test
    fun getRole() {
        // Initialize the database
        roleRepository.save(role)

        val id = role.id
        assertNotNull(id)

        // Get the role
        restRoleMockMvc.perform(get("/api/roles/{id}", id))
            .andExpect(status().isOk)
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.id").value(id))
            .andExpect(jsonPath("$.roleName").value(DEFAULT_ROLE_NAME))
            .andExpect(jsonPath("$.roleAlias").value(DEFAULT_ROLE_ALIAS))
            .andExpect(jsonPath("$.status").value(DEFAULT_STATUS))
            .andExpect(jsonPath("$.sort").value(DEFAULT_SORT))
            .andExpect(jsonPath("$.remark").value(DEFAULT_REMARK))
    }

    @Test
    fun getNonExistingRole() {
        // Get the role
        restRoleMockMvc.perform(get("/api/roles/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound)
    }

    @Test
    fun updateRole() {
        // Initialize the database
        roleRepository.save(role)

        val databaseSizeBeforeUpdate = roleRepository.findAll().size

        // Update the role
        val id = role.id
        assertNotNull(id)
        val updatedRole = roleRepository.findById(id).get()
        updatedRole.roleName = UPDATED_ROLE_NAME
        updatedRole.roleAlias = UPDATED_ROLE_ALIAS
        updatedRole.status = UPDATED_STATUS
        updatedRole.sort = UPDATED_SORT
        updatedRole.remark = UPDATED_REMARK
        val roleDTO = roleMapper.toDto(updatedRole)

        restRoleMockMvc.perform(
            put("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isOk)

        // Validate the Role in the database
        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeUpdate)
        val testRole = roleList[roleList.size - 1]
        assertThat(testRole.roleName).isEqualTo(UPDATED_ROLE_NAME)
        assertThat(testRole.roleAlias).isEqualTo(UPDATED_ROLE_ALIAS)
        assertThat(testRole.status).isEqualTo(UPDATED_STATUS)
        assertThat(testRole.sort).isEqualTo(UPDATED_SORT)
        assertThat(testRole.remark).isEqualTo(UPDATED_REMARK)
    }

    @Test
    fun updateNonExistingRole() {
        val databaseSizeBeforeUpdate = roleRepository.findAll().size

        // Create the Role
        val roleDTO = roleMapper.toDto(role)

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restRoleMockMvc.perform(
            put("/api/roles")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(roleDTO))
        ).andExpect(status().isBadRequest)

        // Validate the Role in the database
        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeUpdate)
    }

    @Test
    fun deleteRole() {
        // Initialize the database
        roleRepository.save(role)

        val databaseSizeBeforeDelete = roleRepository.findAll().size

        val id = role.id
        assertNotNull(id)

        // Delete the role
        restRoleMockMvc.perform(
            delete("/api/roles/{id}", id)
                .accept(TestUtil.APPLICATION_JSON_UTF8)
        ).andExpect(status().isNoContent)

        // Validate the database is empty
        val roleList = roleRepository.findAll()
        assertThat(roleList).hasSize(databaseSizeBeforeDelete - 1)
    }

    @Test
    fun equalsVerifier() {
        TestUtil.equalsVerifier(Role::class.java)
        val role1 = Role()
        role1.id = "id1"
        val role2 = Role()
        role2.id = role1.id
        assertThat(role1).isEqualTo(role2)
        role2.id = "id2"
        assertThat(role1).isNotEqualTo(role2)
        role1.id = null
        assertThat(role1).isNotEqualTo(role2)
    }

    @Test
    fun dtoEqualsVerifier() {
        TestUtil.equalsVerifier(RoleDTO::class.java)
        val roleDTO1 = RoleDTO()
        roleDTO1.id = "id1"
        val roleDTO2 = RoleDTO()
        assertThat(roleDTO1).isNotEqualTo(roleDTO2)
        roleDTO2.id = roleDTO1.id
        assertThat(roleDTO1).isEqualTo(roleDTO2)
        roleDTO2.id = "id2"
        assertThat(roleDTO1).isNotEqualTo(roleDTO2)
        roleDTO1.id = null
        assertThat(roleDTO1).isNotEqualTo(roleDTO2)
    }

    companion object {

        private const val DEFAULT_ROLE_NAME: String = "AAAAAAAAAA"
        private const val UPDATED_ROLE_NAME = "BBBBBBBBBB"

        private const val DEFAULT_ROLE_ALIAS: String = "AAAAAAAAAA"
        private const val UPDATED_ROLE_ALIAS = "BBBBBBBBBB"

        private const val DEFAULT_STATUS: Int = 1
        private const val UPDATED_STATUS: Int = 2

        private const val DEFAULT_SORT: Int = 1
        private const val UPDATED_SORT: Int = 2

        private const val DEFAULT_REMARK: String = "AAAAAAAAAA"
        private const val UPDATED_REMARK = "BBBBBBBBBB"

        /**
         * Create an entity for this test.
         *
         * This is a static method, as tests for other entities might also need it,
         * if they test an entity which requires the current entity.
         */
        @JvmStatic
        fun createEntity(): Role {
            val role = Role(
                roleName = DEFAULT_ROLE_NAME,
                roleAlias = DEFAULT_ROLE_ALIAS,
                status = DEFAULT_STATUS,
                sort = DEFAULT_SORT,
                remark = DEFAULT_REMARK
            )
            return role
        }
    }
}
